home *** CD-ROM | disk | FTP | other *** search
/ Developer CD Series 2000 November: Tool Chest / Dev.CD Nov 00 TC Disk 2.toast / pc / sample code / quicktime / basics / qtmovietrack / application files / comapplication.c next >
Encoding:
Text File  |  2000-09-28  |  15.5 KB  |  611 lines

  1. //////////
  2. //
  3. //    File:        ComApplication.c
  4. //
  5. //    Contains:    Application-specific code for basic QuickTime movie display and control.
  6. //
  7. //    Written by:    Tim Monroe
  8. //                Based on the QTShell code written by Tim Monroe, which in turn was based on the MovieShell
  9. //                code written by Kent Sandvik (Apple DTS). This current version is now very far removed from
  10. //                MovieShell.
  11. //
  12. //    Copyright:    © 1999 by Apple Computer, Inc., all rights reserved.
  13. //
  14. //    Change History (most recent first):
  15. //       
  16. //       <2>         03/02/00    rtm        made changes to get things running under CarbonLib
  17. //       <1>         11/05/99    rtm        first file
  18. //
  19. //////////
  20.  
  21. //////////
  22. //
  23. // header files
  24. //
  25. //////////
  26.  
  27. #include "ComApplication.h"
  28. #include "QTMovieTrack.h"
  29.  
  30.  
  31. //////////
  32. //
  33. // global variables
  34. //
  35. //////////
  36.  
  37. #if TARGET_OS_MAC
  38. AEEventHandlerUPP        gHandleOpenAppAEUPP;                    // UPPs for our Apple event handlers
  39. AEEventHandlerUPP        gHandleOpenDocAEUPP;
  40. AEEventHandlerUPP        gHandlePrintDocAEUPP;
  41. AEEventHandlerUPP        gHandleQuitAppAEUPP;
  42. extern Boolean            gAppInForeground;                        // is our application in the foreground?    
  43. #endif
  44.  
  45. #if TARGET_OS_WIN32
  46. extern HWND                ghWnd;                                    // the MDI frame window; this window has the menu bar
  47. #endif
  48.  
  49.  
  50. //////////
  51. //
  52. // QTApp_Init
  53. // Do any application-specific initialization.
  54. //
  55. // The theStartPhase parameter determines which "phase" of application start-up is executed,
  56. // *before* the MDI frame window is created or *after*. This distinction is relevant only on
  57. // Windows, so on MacOS, you should always use kInitAppPhase_BothPhases.
  58. //
  59. //////////
  60.  
  61. void QTApp_Init (UInt32 theStartPhase)
  62. {
  63.     // do any start-up activities that should occur before the MDI frame window is created
  64.     if (theStartPhase & kInitAppPhase_BeforeCreateFrameWindow) {
  65. #if TARGET_OS_MAC
  66.         // make sure that the Apple Event Manager is available; install handlers for required Apple events
  67.         QTApp_InstallAppleEventHandlers();
  68. #endif
  69.     }
  70.  
  71.     // do any start-up activities that should occur after the MDI frame window is created
  72.     if (theStartPhase & kInitAppPhase_AfterCreateFrameWindow) {
  73. #if TARGET_OS_WIN32
  74.         // on Windows, open as movie documents any files specified on the command line
  75.         SendMessage(ghWnd, WM_OPENDROPPEDFILES, 0L, 0L);
  76. #endif
  77.     }
  78. }
  79.  
  80.  
  81. //////////
  82. //
  83. // QTApp_Stop
  84. // Do any application-specific shut-down.
  85. //
  86. // The theStopPhase parameter determines which "phase" of application shut-down is executed,
  87. // *before* any open movie windows are destroyed or *after*.
  88. //
  89. //////////
  90.  
  91. void QTApp_Stop (UInt32 theStopPhase)
  92. {    
  93.     // do any shut-down activities that should occur before the movie windows are destroyed
  94.     if (theStopPhase & kStopAppPhase_BeforeDestroyWindows) {
  95.         
  96.     }
  97.     
  98.     // do any shut-down activities that should occur after the movie windows are destroyed
  99.     if (theStopPhase & kStopAppPhase_AfterDestroyWindows) {
  100. #if TARGET_OS_MAC
  101.         // dispose of routine descriptors for Apple event handlers
  102.         DisposeAEEventHandlerUPP(gHandleOpenAppAEUPP);
  103.         DisposeAEEventHandlerUPP(gHandleOpenDocAEUPP);
  104.         DisposeAEEventHandlerUPP(gHandlePrintDocAEUPP);
  105.         DisposeAEEventHandlerUPP(gHandleQuitAppAEUPP);
  106. #endif
  107.     
  108.     }
  109. }
  110.  
  111.  
  112. //////////
  113. //
  114. // QTApp_Idle
  115. // Do any processing that can/should occur at idle time.
  116. //
  117. //////////
  118.  
  119. void QTApp_Idle (WindowReference theWindow)
  120. {
  121.     WindowObject         myWindowObject = NULL;
  122.     GrafPtr             mySavedPort;
  123.     
  124.     GetPort(&mySavedPort);
  125.     MacSetPort(QTFrame_GetPortFromWindowReference(theWindow));
  126.     
  127.     myWindowObject = QTFrame_GetWindowObjectFromWindow(theWindow);
  128.     if (myWindowObject != NULL) {
  129.         MovieController        myMC = NULL;
  130.     
  131.         myMC = (**myWindowObject).fController;
  132.         if (myMC != NULL) {
  133.             
  134.             // run any idle-time tasks for the movie
  135.             
  136. #if TARGET_OS_MAC
  137.             // restore the cursor to the arrow
  138.             // if it's outside the front movie window or outside the window's visible region
  139.             if (theWindow == QTFrame_GetFrontMovieWindow()) {
  140.                 Rect            myRect;
  141.                 Point            myPoint;
  142.                 RgnHandle        myVisRegion;
  143.                 Cursor            myArrow;
  144.                 
  145.                 GetMouse(&myPoint);
  146.                 myVisRegion = NewRgn();
  147.                 GetPortVisibleRegion(QTFrame_GetPortFromWindowReference(theWindow), myVisRegion);
  148.                 GetWindowPortBounds(theWindow, &myRect);
  149.                 if (!MacPtInRect(myPoint, &myRect) || !PtInRgn(myPoint, myVisRegion))
  150.                     MacSetCursor(GetQDGlobalsArrow(&myArrow));
  151.                     
  152.                 DisposeRgn(myVisRegion);
  153.             }
  154. #endif // TARGET_OS_MAC
  155.         }
  156.     }
  157.     
  158.     // ***insert application-specific idle-time processing here***
  159.     
  160.     MacSetPort(mySavedPort);
  161. }
  162.  
  163.  
  164. //////////
  165. //
  166. // QTApp_Draw
  167. // Update the specified window.
  168. //
  169. //////////
  170.  
  171. void QTApp_Draw (WindowReference theWindow, Rect *theRefreshArea)
  172. {
  173. #pragma unused(theRefreshArea)
  174.  
  175.     GrafPtr             mySavedPort;
  176.     
  177.     GetPort(&mySavedPort);
  178.     MacSetPort(QTFrame_GetPortFromWindowReference(theWindow));
  179.     
  180.     BeginUpdate(QTFrame_GetWindowFromWindowReference(theWindow));
  181.     //EraseRect(theRefreshArea);        // this is important only for non-rectangular movies
  182.     
  183.     // ***insert application-specific drawing here***
  184.     
  185.     // draw the movie controller and its movie
  186.     MCDoAction(QTFrame_GetMCFromWindow(theWindow), mcActionDraw, theWindow);
  187.     
  188.     EndUpdate(QTFrame_GetWindowFromWindowReference(theWindow));
  189.     MacSetPort(mySavedPort);
  190. }
  191.  
  192.  
  193. //////////
  194. //
  195. // QTApp_HandleContentClick
  196. // Handle mouse button clicks in the specified window.
  197. //
  198. //////////
  199.  
  200. void QTApp_HandleContentClick (WindowReference theWindow, EventRecord *theEvent)
  201. {
  202. #pragma unused(theEvent)
  203.  
  204.     GrafPtr             mySavedPort;
  205.     
  206.     GetPort(&mySavedPort);
  207.     MacSetPort(QTFrame_GetPortFromWindowReference(theWindow));
  208.     
  209.     // ***insert application-specific content-click processing here***
  210.  
  211.     MacSetPort(mySavedPort);
  212. }
  213.  
  214.  
  215. //////////
  216. //
  217. // QTApp_HandleKeyPress
  218. // Handle application-specific key presses.
  219. // Returns true if the key press was handled, false otherwise.
  220. //
  221. //////////
  222.  
  223. Boolean QTApp_HandleKeyPress (char theCharCode)
  224. {
  225.     Boolean        isHandled = true;
  226.     
  227.     switch (theCharCode) {
  228.     
  229.         // ***insert application-specific key-press processing here***
  230.  
  231.         default:
  232.             isHandled = false;
  233.             break;
  234.     }
  235.  
  236.     return(isHandled);
  237. }
  238.  
  239.  
  240. //////////
  241. //
  242. // QTApp_HandleMenu
  243. // Handle selections in the application's menus.
  244. //
  245. // The theMenuItem parameter is a UInt16 version of the Windows "menu item identifier". 
  246. // When called from Windows, theMenuItem is simply the menu item identifier passed to the window procedure.
  247. // When called from MacOS, theMenuItem is constructed like this:
  248. //     *high-order 8 bits == the Macintosh menu ID (1 thru 256)
  249. //     *low-order 8 bits == the Macintosh menu item (sequential from 1 to ordinal of last menu item in menu)
  250. // In this way, we can simplify the menu-handling code. There are, however, some limitations, mainly that
  251. // the menu item identifiers on Windows must be derived from the Mac values. 
  252. //
  253. //////////
  254.  
  255. Boolean QTApp_HandleMenu (UInt16 theMenuItem)
  256. {
  257.     WindowObject        myWindowObject = NULL;
  258.     Movie                 myMovie = NULL;
  259.     Boolean                myIsHandled = false;            // false => allow caller to process the menu item
  260.     OSErr                myErr = noErr;
  261.     
  262.     myWindowObject = QTFrame_GetWindowObjectFromFrontWindow();
  263.     if (myWindowObject != NULL)
  264.         myMovie = (**myWindowObject).fMovie;
  265.     
  266.     // make sure we have a valid movie
  267.     if (myMovie == NULL)
  268.         return(myIsHandled);
  269.  
  270.     switch (theMenuItem) {
  271.     
  272.         case IDM_ADD_FILE_AS_MOVIE_TRACK:
  273.             myErr = QTMIM_ShowPropertiesDialogBox(myWindowObject);
  274.             if (myErr == noErr)
  275.                 myErr = QTMIM_AddFileAsMovieTrack(myWindowObject);
  276.             if (myErr == noErr)
  277.                 (**myWindowObject).fIsDirty = true;
  278.             break;
  279.  
  280.         case IDM_ADD_URL_AS_MOVIE_TRACK:
  281.             myErr = QTMIM_ShowPropertiesDialogBox(myWindowObject);
  282.             if (myErr == noErr)
  283.                 myErr = QTMIM_AddURLAsMovieTrack(myWindowObject);
  284.             if (myErr == noErr)
  285.                 (**myWindowObject).fIsDirty = true;
  286.             break;
  287.  
  288.         default:
  289.             break;
  290.             
  291.     } // switch (theMenuItem)
  292.     
  293.     return(myIsHandled);
  294. }
  295.  
  296.  
  297. //////////
  298. //
  299. // QTApp_AdjustMenus
  300. // Adjust state of items in the application's menus.
  301. //
  302. // Currently, the Mac application has only one app-specific menu ("Test"); you could change that.
  303. //
  304. //////////
  305.  
  306. void QTApp_AdjustMenus (WindowReference theWindow, MenuReference theMenu)
  307. {
  308. #if TARGET_OS_MAC
  309. #pragma unused(theMenu)
  310. #endif
  311.  
  312.     WindowObject        myWindowObject = NULL; 
  313.     Movie                 myMovie = NULL;
  314.     MenuReference        myMenu;
  315.     
  316. #if TARGET_OS_WIN32
  317.     myMenu = theMenu;
  318. #endif
  319. #if TARGET_OS_MAC
  320.     myMenu = GetMenuHandle(kTestMenuResID);
  321. #endif
  322.     
  323.     if (theWindow != NULL)
  324.         myWindowObject = QTFrame_GetWindowObjectFromWindow(theWindow);
  325.  
  326.     if (myWindowObject != NULL)
  327.         myMovie = (**myWindowObject).fMovie;
  328.  
  329.     QTFrame_SetMenuItemState(myMenu, IDM_ADD_FILE_AS_MOVIE_TRACK, myMovie == NULL ? kDisableMenuItem : kEnableMenuItem);
  330.     QTFrame_SetMenuItemState(myMenu, IDM_ADD_URL_AS_MOVIE_TRACK, myMovie == NULL ? kDisableMenuItem : kEnableMenuItem);
  331. }
  332.  
  333.  
  334. //////////
  335. //
  336. // QTApp_HandleEvent
  337. // Perform any application-specific event loop actions.
  338. //
  339. // Return true to indicate that we've completely handled the event here, false otherwise.
  340. //
  341. //////////
  342.  
  343. Boolean QTApp_HandleEvent (EventRecord *theEvent)
  344. {
  345. #pragma unused(theEvent)
  346.  
  347.     // ***insert application-specific event handling here***
  348.     
  349.     return(false);            // no-op for now
  350. }
  351.  
  352.  
  353. //////////
  354. //
  355. // QTApp_SetupController
  356. // Configure the movie controller.
  357. //
  358. //////////
  359.  
  360. void QTApp_SetupController (MovieController theMC)
  361. {
  362.     long            myControllerFlags;
  363.     
  364.     // CLUT table use
  365.     MCDoAction(theMC, mcActionGetFlags, &myControllerFlags);
  366.     MCDoAction(theMC, mcActionSetFlags, (void *)(myControllerFlags | mcFlagsUseWindowPalette));
  367.  
  368.     // enable keyboard event handling
  369.     MCDoAction(theMC, mcActionSetKeysEnabled, (void *)true);
  370.     
  371.     // disable drag support
  372.     MCDoAction(theMC, mcActionSetDragEnabled, (void *)false);
  373. }
  374.  
  375.  
  376. //////////
  377. //
  378. // QTApp_SetupWindowObject
  379. // Do any application-specific initialization of the window object.
  380. //
  381. //////////
  382.  
  383. void QTApp_SetupWindowObject (WindowObject theWindowObject)
  384. {
  385.     ApplicationDataHdl        myAppData = NULL;
  386.         
  387.     if (theWindowObject == NULL)
  388.         return;
  389.  
  390.     myAppData = (ApplicationDataHdl)NewHandleClear(sizeof(ApplicationDataRecord));
  391.     (**theWindowObject).fAppData = (Handle)myAppData;
  392. }
  393.  
  394.  
  395. //////////
  396. //
  397. // QTApp_RemoveWindowObject
  398. // Do any application-specific clean-up of the window object.
  399. //
  400. //////////
  401.  
  402. void QTApp_RemoveWindowObject (WindowObject theWindowObject)
  403. {
  404.     ApplicationDataHdl        myAppData = NULL;
  405.         
  406.     if (theWindowObject == NULL)
  407.         return;
  408.  
  409.     if ((**theWindowObject).fAppData != NULL)
  410.         DisposeHandle((Handle)(**theWindowObject).fAppData);
  411.  
  412.     // QTFrame_DestroyMovieWindow in MacFramework.c or QTFrame_MovieWndProc in WinFramework.c
  413.     // releases the window object itself
  414. }
  415.  
  416.  
  417. //////////
  418. //
  419. // QTApp_MCActionFilterProc 
  420. // Intercept some actions for the movie controller.
  421. //
  422. // NOTE: The theRefCon parameter is a handle to a window object record.
  423. //
  424. //////////
  425.  
  426. PASCAL_RTN Boolean QTApp_MCActionFilterProc (MovieController theMC, short theAction, void *theParams, long theRefCon)
  427. {
  428. #pragma unused(theMC, theParams)
  429.  
  430.     Boolean                isHandled = false;            // false => allow controller to process the action
  431.     WindowObject        myWindowObject = NULL;
  432.     
  433.     myWindowObject = (WindowObject)theRefCon;
  434.     if (myWindowObject == NULL)
  435.         return(isHandled);
  436.         
  437.     switch (theAction) {
  438.     
  439.         // handle window resizing
  440.         case mcActionControllerSizeChanged:
  441.             if (MCIsControllerAttached(theMC) == 1)
  442.                 QTFrame_SizeWindowToMovie(myWindowObject);
  443.             break;
  444.  
  445.         // handle idle events
  446.         case mcActionIdle:
  447.             QTApp_Idle((**myWindowObject).fWindow);
  448.             break;
  449.             
  450.         default:
  451.             break;
  452.             
  453.     } // switch (theAction)
  454.     
  455.     return(isHandled);    
  456. }
  457.  
  458.  
  459. #if TARGET_OS_MAC
  460. ///////////////////////////////////////////////////////////////////////////////////////////////////////////
  461. //
  462. // Apple Event functions.
  463. //
  464. // Use these functions to install handlers for Apple Events and to handle those events.
  465. //
  466. ///////////////////////////////////////////////////////////////////////////////////////////////////////////
  467.  
  468. //////////
  469. //
  470. // QTApp_InstallAppleEventHandlers 
  471. // Install handlers for Apple Events.
  472. //
  473. //////////
  474.  
  475. void QTApp_InstallAppleEventHandlers (void)
  476. {
  477.     long        myAttrs;
  478.     OSErr        myErr = noErr;
  479.     
  480.     // see whether the Apple Event Manager is available in the present operating environment;
  481.     // if it is, install handlers for the four required Apple Events
  482.     myErr = Gestalt(gestaltAppleEventsAttr, &myAttrs);
  483.     if (myErr == noErr) {
  484.         if (myAttrs & (1L << gestaltAppleEventsPresent)) {
  485.             // create routine descriptors for the Apple event handlers
  486.             gHandleOpenAppAEUPP = NewAEEventHandlerUPP(QTApp_HandleOpenApplicationAppleEvent);
  487.             gHandleOpenDocAEUPP = NewAEEventHandlerUPP(QTApp_HandleOpenDocumentAppleEvent);
  488.             gHandlePrintDocAEUPP = NewAEEventHandlerUPP(QTApp_HandlePrintDocumentAppleEvent);
  489.             gHandleQuitAppAEUPP = NewAEEventHandlerUPP(QTApp_HandleQuitApplicationAppleEvent);
  490.             
  491.             // install the handlers
  492.             AEInstallEventHandler(kCoreEventClass, kAEOpenApplication, gHandleOpenAppAEUPP, 0L, false);
  493.             AEInstallEventHandler(kCoreEventClass, kAEOpenDocuments, gHandleOpenDocAEUPP, 0L, false);
  494.             AEInstallEventHandler(kCoreEventClass, kAEPrintDocuments, gHandlePrintDocAEUPP, 0L, false);
  495.             AEInstallEventHandler(kCoreEventClass, kAEQuitApplication, gHandleQuitAppAEUPP, 0L, false);
  496.         }
  497.     }
  498. }
  499.         
  500.         
  501. //////////
  502. //
  503. // QTApp_HandleOpenApplicationAppleEvent 
  504. // Handle the open-application Apple Events.
  505. //
  506. //////////
  507.  
  508. PASCAL_RTN OSErr QTApp_HandleOpenApplicationAppleEvent (const AppleEvent *theMessage, AppleEvent *theReply, unsigned long theRefcon)            
  509. {
  510. #pragma unused(theMessage, theReply, theRefcon)
  511.     
  512.     // we don't need to do anything special when opening the application
  513.     return(noErr);
  514. }
  515.  
  516.  
  517. //////////
  518. //
  519. // QTApp_HandleOpenDocumentAppleEvent 
  520. // Handle the open-document Apple Events. This is based on Inside Macintosh: IAC, pp. 4-15f.
  521. //
  522. // Here we process an Open Documents AE only for files of type MovieFileType.
  523. //
  524. //////////
  525.  
  526. PASCAL_RTN OSErr QTApp_HandleOpenDocumentAppleEvent (const AppleEvent *theMessage, AppleEvent *theReply, unsigned long theRefcon)            
  527. {
  528. #pragma unused(theReply, theRefcon)
  529.  
  530.     long            myIndex;
  531.     long            myItemsInList;
  532.     AEKeyword        myKeyWd;
  533.     AEDescList          myDocList;
  534.     long            myActualSize;
  535.     DescType        myTypeCode;
  536.     FSSpec            myFSSpec;
  537.     OSErr            myIgnoreErr = noErr;
  538.     OSErr            myErr = noErr;
  539.     
  540.     // get the direct parameter and put it into myDocList
  541.     myDocList.dataHandle = NULL;
  542.     myErr = AEGetParamDesc(theMessage, keyDirectObject, typeAEList, &myDocList);
  543.     
  544.     // count the descriptor records in the list
  545.     if (myErr == noErr)
  546.         myErr = AECountItems(&myDocList, &myItemsInList);
  547.     else
  548.         myItemsInList = 0;
  549.     
  550.     // open each specified file
  551.     for (myIndex = 1; myIndex <= myItemsInList; myIndex++)
  552.         if (myErr == noErr) {
  553.             myErr = AEGetNthPtr(&myDocList, myIndex, typeFSS, &myKeyWd, &myTypeCode, (Ptr)&myFSSpec, sizeof(myFSSpec), &myActualSize);
  554.             if (myErr == noErr) {
  555.                 FInfo        myFinderInfo;
  556.             
  557.                 // verify that the file type is MovieFileType; to do this, get the Finder information
  558.                 myErr = FSpGetFInfo(&myFSSpec, &myFinderInfo);    
  559.                 if (myErr == noErr) {
  560.                     if (myFinderInfo.fdType == MovieFileType)
  561.                         // we've got a movie file; just open it
  562.                         QTFrame_OpenMovieInWindow(NULL, &myFSSpec);
  563.                 }
  564.             }
  565.         }
  566.  
  567.     if (myDocList.dataHandle)
  568.         myIgnoreErr = AEDisposeDesc(&myDocList);
  569.     
  570.     // make sure we open the document in the foreground        
  571.     gAppInForeground = true;
  572.     return(myErr);
  573. }
  574.  
  575.  
  576. //////////
  577. //
  578. // QTApp_HandlePrintDocumentAppleEvent 
  579. // Handle the print-document Apple Events.
  580. //
  581. // NOT YET IMPLEMENTED.
  582. //
  583. //////////
  584.  
  585. PASCAL_RTN OSErr QTApp_HandlePrintDocumentAppleEvent (const AppleEvent *theMessage, AppleEvent *theReply, unsigned long theRefcon)            
  586. {
  587. #pragma unused(theMessage, theReply, theRefcon)
  588.  
  589.     return(errAEEventNotHandled);
  590. }
  591.  
  592.  
  593. //////////
  594. //
  595. // QTApp_HandleQuitApplicationAppleEvent 
  596. // Handle the quit-application Apple Events.
  597. //
  598. //////////
  599.  
  600. PASCAL_RTN OSErr QTApp_HandleQuitApplicationAppleEvent (const AppleEvent *theMessage, AppleEvent *theReply, unsigned long theRefcon)            
  601. {
  602. #pragma unused(theMessage, theReply, theRefcon)
  603.  
  604.     // close down the entire framework and application
  605.     QTFrame_QuitFramework();
  606.     return(noErr);
  607. }
  608. #endif // TARGET_OS_MAC
  609.  
  610.  
  611.